Assembly Language
©
Copyright Brian Brown, 1988-2000. All rights reserved.
| Notes | Home Page |
INTERRUPTS
An interrupt is an unexpected hardware initiated
subroutine call or jump that temporarily suspends the running of the current
program.
Interrupts occur when a peripheral device asserts an interrupt input pin of the micro-processor. Provided the interrupt is permitted, it will be acknowledged by the processor at the end of the current memory cycle. The processor then services the interrupt by branching to a special service routine written to handle that particular interrupt. Upon servicing the device, the processor is then instructed to continue with what is was doing previously (by use of a special "return from interrupt" instruction).
Interrupts fall into two major categories, maskable and non-maskable. An interrupt may be either EDGE or LEVEL sensitive.
Edge level interrupts are recognised on the falling or rising edge of the input signal. They are generally used for high priority interrupts and are latched internally inside the processor. If this latching was not done, the processor could easily miss the falling edge (due to its short duration) and thus not respond to the interrupt request.
Level sensitive interrupts overcome the problem of latching, in that the requesting device holds the interrupt line at a specified logic state (normally logic zero) till the processor acknowledges the interrupt. This type of interrupt can be shared by other devices in a wired or configuration, thus is commonly used to support daisy chaining and other techniques.
Maskable Interrupts
The processor can inhibit certain types of
interrupts by use of a special interrupt mask bit. This mask bit is part of the
condition code register, or a special interrupt register. If this bit is set,
and an interrupt request occurs on the Interrupt Request input, it is ignored.
Non-Maskable Interrupts
There are some interrupts which cannot be
masked out or ignored by the processor. These are associated with high priority
tasks which cannot be ignored (like memory parity or bus faults). In general,
most processors support the Non-Maskable Interrupt (NMI). This interrupt has
absolute priority, and when it occurs, the processor will finish the current
memory cycle, then branch to a special routine written to handle the interrupt
request.
Advantages of Interrupts
Interrupts are used to ensure adequate
service response times by the processing. Sometimes, with software polling
routines, service times by the processor cannot be guaranteed, and data may be
lost. The use of interrupts guarantees that the processor will service the
request within a specified time period, reducing the likelihood of lost data.
Maskable NonMaskable Acknowledge 68000 IPL0-IPL2 Where IPL0-IPL2 = 7 FC0-FC2 (111) RESET iAPX386 INTR NMI M/IO=0 RESET D/C=0 W/R=0
68000
The 68000 uses three input lines, which are priority encoded.
A level 7 cannot be masked. The interrupt lines must remain stable until the
68000 signals interrupt acknowledge.
iAPX386
INTR is level sensitive, and must remain asserted until the
iAPX386 generates the interrupt acknowledge signal. NMI is rising edge sensitive
and must be negated for at least eight CLK2 periods, then asserted for at least
eight CLK2 periods. Once NMI is accepted, no further NMI's are processed till an
IRET is executed.
The Use of Interrupts
The use of interrupts generally falls into
the following categories,
I/O data transfers are more efficient when interrupt driven, because the processor is released from software polling. The device requests transfer only when there is data to be moved, so the processor does not need to continually poll the device. This releases the CPU to perform other tasks during this period.
The Basic steps involved in interrupt processing are
68000
A device requests an interrupt by presenting a priority
level between 1 and 7 to the processor. The interrupt is accepted ONLY if the
current processor priority level (in SR) is less than the interrupt level, OR
if the request level is 7. Level 7 is equivalent to NMI.
iAPX386
INTR interrupt requests are enabled using the STI
instruction (and disabled using CLI). The NMI is always enabled except where
the processor is currently servicing an NMI request.
68000
An interrupt is asserted by presenting a priority level of
between 1 and 7 to the processor on the IPL0-IPL2 lines.
iAPX386
An INTR is performed by asserting the INTR pin high. An
NMI is performed by asserting the NMI pin high.
68000
The 68000 asserts FC0-FC2 high to indicate an interrupt
acknowledge. The requesting device may either supply an interrupt vector
number, or indicate auto-vectoring, in which case the vector numbers are 25 to
31, according to the priority level on IPL0-IPL2. The program counter and
status register is saved on the stack.
The priority level in the status register is set to the level of the interrupt, which prevents further interrupts of the same or lower levels. The supervisor bit is enabled and the trace bit turned off.
iAPX386
When the INTR occurs, if the Interrupt Flag bit (IF) is
enabled, the processor reads an 8-bit vector (using D0-D7) supplied by the
interrupting device, which identifies the source of the interrupt. The IF bit
is reset when the interrupt is being serviced, effectively disabling further
interrupts. It may be set by the interrupt handler to allow nesting
interrupts. When the IRET instruction is executed, the original state of the
IF bit is restored.
When the NMI occurs, the processor uses an internal vector address of 2. No interrupt acknowledge signal is generated, and the processor ignores further NMI requests whilst servicing the current NMI. The IF bit is cleared on entry to the NMI service routine, which prevents furthet INTR interrupt requests.
The interrupt vector is supplied from the IDT descriptor entries when running in protected mode. The tables base address and limit is stored in IDTR, and each descriptor is eight bytes long. Which descriptor is referenced depends upon the 8 bit vector supplied by the interrupting device. The program counter and EFLAG is saved on the stack.
68000
The 68000 uses the Return from Exception (RTE) instruction
to restore the machine state to that which existed prior to the interrupt
occurring. The PC and status register are restored from the supervisor stack.
This is forbidden if the processor is running in user state, as the
instruction sets the status register directly, which would permit a means of
enabling supervisor mode.
iAPX386
The Interrupt Return (IRET) instruction restores the
machine state, loading the CS, PC and EFLAGS from the stack. Other exceptions
require popping off the error code before executing the IRET (8, 10-14).
ACCOMPLISHING INPUT/OUTPUT DATA TRANSFER
There are three main
methods used to perform/control input/output data transfers. They are,
Programmed I/O or Polling
In programmed I/O, all transfers to and
from devices is performed by the processor. The processor sends and requests
data; all input and output operations are under the control of the program being
executed. The transfers are co-ordinated by the use of a special handshake
protocol.
To determine if an I/O request is pending, the processor scans each device. If the device is requesting service, it will set a special flag. The flags of the various devices are continuously checked using a scanning loop program. When the processor finds a devices flag set, it branches to the appropriate service routine, and after the service is completed, resumes the polling sequence. Such a software polling loop is shown below.
There are two basic methods used in sensing the device-request flags, the use of a simple input status port, and the use of a priority-encoder input-status port.
A Simple Input-Status Port
The various devices are connected to a
decoded location, each device utilising a single bit line. By reading this
location, the CPU can determine which device is requesting service.
The Priority-Encoded Input-Status Port
The decoded location is
connected to the output of a priority encoder. The input of the priority encoder
is connected to each device. When a device requests service, the priority
encoder presents a special code combination (unique for each device) to the
decoded memory location. The port thus holds the value or address associated
with the highest device requesting service.
The priority encoder arranges all devices in a list, devices given a lower priority are serviced when no other higher priority devices need servicing. This simplifies the software required to determine the device, resulting in an increase in speed.
The disadvantages are
Summary of Software Polled I/O
Polling is the most common and
simplest method of I/O control. It requires no special hardware and all I/O
transfers are controlled by the CPU program. Polling is a synchronous mechanism,
by which devices are serviced in sequential order.
The polling technique, however, has limitations.
Interrupt Controlled I/O Transfers
Interrupts are an asynchronous
mechanism. Each device is connected to an interrupt line. When a device needs
service, it asserts the interrupt line to request the processors attention.
The processor checks for pending interrupts at the end of every memory cycle. Interrupts can be masked, or non-maskable. Once the interrupt has been recognized by the processor and accepted, the device must be serviced. This is done by forcing the processor to a specialized service routine.
The status of the program being executed must first be saved. The processors registers will be saved on the stack, or, at very least, the program counter will be saved. Preserving those registers which are not saved will be the responsibility of the interrupt service routine. Once the program counter has been saved, the processor will branch to the address of the service routine.
If more than one device is connected to the interrupt line, the processor needs to know to which device service routine it should branch to. The identification of the device requesting service can be done in either hardware or software, or a combination of both.
Software Determination of the Requesting Device
A software routine
is used to identify the device requesting service. A simple polling technique is
used, each device is checked to see if it was the one needing service.
Having identified the device, the processor then branches to the appropriate interrupt-handling-routine address for the given device. The order in which the devices appear in the polling sequence determines their priority.
Software/Hardware Driven Identification (Daisy Chain)
This is
significantly faster than a pure software approach. A daisy chain is used to
identify the device requesting service.
Daisy chaining is used for level sensitive interrupts, which act like a wired or gate. Any requesting device can take the interrupt line low, and keep it asserted low until it is serviced.
Because more than one device can assert the shared interrupt line simultaneously, some method must be employed to ensure device priority. This is done using the interrupt acknowledge signal generated by the processor is response to an interrupt request.
Each device is connected to the same interrupt request line, but the interrupt acknowledge line is passed through each device, from the highest priority device first, to the lowest priority device last.
After preserving the required registers, the microprocessor generates an interrupt acknowledge signal. This is gated through each device. If device 1 generated the interrupt, it will place its identification signal on the data bus, which is read by the processor, and used to generate the address of the interrupt-service routine. If device 1 did not request the servicing, it will pass the interrupt acknowledge signal on to the next device in the chain. Device 2 follows the same procedure, and so on.
Hardware Identification (Vectored Interrupts)
This is the fastest
system. The onus is placed on the requesting device to request the interrupt,
and identify itself. The identity could be a branching address for the desired
interrupt-handling routine.
If the device just supplies an identification number, this can be used in conjunction with a lookup table to determine the address of the required service routine. Response time is best when the device requesting service also supplies a branching address.
Priority Interrupt Controller Chips (PIC's) are hardware chips designed to make the task of a device presenting its own address to the CPU simple. The PIC also assesses the priority of the devices connected to it. Modern PIC's can also be programmed to prevent the generation of interrupts which are lower than a desired level.
DIRECT MEMORY ACCESS
Interrupts guarantee the fastest possible
response time to an I/O device requesting service. However, the servicing of the
device is still accomplished using software.
This may not be fast enough, for example, to transfer raw data between disks and memory. The solution is to replace the software routines which do the transferring of data with a hardware device(s).
The software routine is replaced with a specialized hardware processor, the Direct Memory Access Controller, or DMAC for short.
Direct memory access (DMA) is a hardware technique used to transfer data between prime memory and peripheral devices. In order to perform the transfer of data, the DMAC requires access to the processors address and data buses.
DMAC options for data transfer
The DMAC has several options
available for the transfer of data. They are,
The simplest approach is to suspend the processor.
Bus Arbitration
Most processors use special control lines for bus
arbitration, ie, controlling the use of the address and data bus,
Because the DMAC must drive the address and data buses of the processor, it is necessary for the processor to be able to tri-state these buses in response to a bus request by the DMAC.
DMAC Controller Operation
The diagram illustrates the various
stages in DMA data transfer. When the DMAC receives an interrupt from the device
requesting service, it generates a special signal for the microprocessor, the
HOLD signal.
The microprocessor then completes its current memory cycle, and tri-states the address and data buses. The CPU then responds with a HOLD ACKNOWLEDGE signal.
This informs the DMAC that the buses are available for use. It then places an address on the address bus which specifies the address at which the data transfer is to take place.
A read or write signal is then generated by the DMAC, and the I/O device either generates or latches the data. The DMAC effectively steals cycles from the processor in order to transfer the byte, so single byte transfer is also known as cycle stealing.
To achieve block transfers, some DMAC's incorporate an automatic sequencing of the value presented on the address bus. A register is used as a byte count, being decremented for each byte transfer, and upon the byte count reaching zero, the DMAC will release the bus.
When the DMAC operates in burst mode, the CPU is halted for the duration of the data transfer.
Memory Considerations
The speed of memory in a micro-processor
based system is the limiting factor on the DMA transfer rate. If the system RAM
has a cycle time of 500ns, this means the memory has a bandwidth of 2Mhz. DMA
transfers cannot exceed this rate.
Transfers can occur in single bytes, or in bursts of bytes. The type of transfer mode affects the maximum transfer rate also.
If burst mode is used, the effective transfer rate is nearly the same as that of the memory bandwidth, but for single byte transfers, the effective transfer rate is very much slower. This occurs because time is expended in requesting and granting the DMA transfer for each byte.
Hidden DMA transfers
It is possible to perform hidden DMA, which is
transparent to the normal operation of the CPU. In other words, the bus is
grabbed by the DMAC when the processor is not using it.
The DMAC monitors the execution of the processor, and when it recognises the processor executing an instruction which has sufficient empty clock cycles to perform a byte transfer, it waits till the processor is decoding the op code, then grabs the bus during this time.
The processor is not slowed down, but continues processing normally. Naturally, the data transfer by the DMAC must be completed before the processor starts the execute cycle of the op code.
This technique can only be performed with those processors which provide an indication of the machine cycle status. Processors utilising cache and pipelining prohibit the use of this technique, as the processor is likely to be using the bus (pre-fetching) whilst decoding the current op-code.
DMAC's and Operating Systems
In a multi-user system, where many
users compete for limited resources such as RAM, it is common for the operating
system to use either paging (Virtual memory) or segmentation (swapping)
techniques.
In paging, the users program is split up into small blocks called pages, each about 4Kbytes in size. One or more of those pages resides in prime memory, whilst the rest of the pages which make up the users program are stored on disk.
As the user program executes, it is possible for the program to make reference to a page which currently resides on disk. This is called a page fault. The operating system then takes over, locates the required page on disk, and loads it into RAM (it may also swap some other pages out to make room for the new page!) before the users program is allowed to continue.
This operation is best performed with the help of a DMAC. The operating system can load the DMAC chip with the required information, ie, track/sector(s) information, load address, and then instruct the DMAC to perform the transfer. When the transfer is complete, the DMAC will provide a signal to the processor. The processor can then check the status of the DMAC to ensure the operation was performed correctly.
In mainframes, a special device is used to perform data transfers between devices and memory. It is the IBM I/O Channel. There are two basic types, the selector and the multiplexer channel. The selector type operates in burst mode with one device at a time for maximum speed, whereas the multiplexer can work with many sub-devices simultaneously in byte or burst mode.
Bus Request Bus Grant 68000 BR* BG* iAPX386 HOLD HLDA
Direct Memory Access (DMA) and the IBM-PC
DMA is used to transfer
data between I/O devices and memory without the aid of the CPU. The DMA device
takes over the processor busses and transfers the data a single byte at a time,
or as a block (burst mode). In the PC, DMA is performed by the 8237. It is used
primarily for dynamic RAM refresh (psuedo reads) and the floppy diskette
controller.
The 8237 DMA Controller
This chip is reponsible for handling DMA
transfers between various I/O devices and memory. When a device requests
service, it asserts its associated request line (DRQ1 to DRQ3), signalling the
DMA controller. The 8237 then asserts HOLD to the processor which responds with
HLDA (Hold Acknowledge), and floats its busses. Upon receiving this acknowledge,
the 8237 takes over the system bus and performs the transfer.
All DMA channels have access to 1mb memory space (20 bit registers) and have a 64k block limitation. Memory to memory transfers which use channel 0 and 1 are not supported, as channel 0 is used to refresh the system RAM.
On the PC/XT, the 8237 transfers 8 bit values between I/O and memory, and transfers must occur on evenbyte boundarys.
The PC series uses the 8237 DMA Controller Chip which is used as follows,
Channel Purpose 0 Dynamic RAM Refresh 1 SDLC or User programmed 2 Floppy disk 3 Fixed disk Page registers appear at 0x80 to 0x83 Controller appears at 0x00 to 0x0f
When the base address is written, it is the real address divided by 2 that is written to the base register.
The method of initiating a dma transfer is,
Interrupt Latency and Response Time
In responding to interrupts,
designers use several terms to describe specific phases of the interrupt
process.
At times, a processor might ignore requests whilst executing some indivisible instruction stream (read-write-modify cycle). The figure that matters most is the longest possible interrupt latency time. Often the real time executive is executing code which cannot be interrupted, running with interrupts disabled. In these instances, latency will vary considerably depending upon when the interrupt occurs, whether in user code or in the executive.